/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "UI.h"
#include "stdio.h"
#include "tim.h"
#include "semphr.h"
#include "timers.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
// FPS监控相关变量
extern uint8_t UpdateTimer;
static uint32_t frame_count = 0;
static uint32_t last_time = 0;
static uint8_t current_fps = 0;

// 互斥锁用于保护共享资源
osMutexId_t lvgl_mutexHandle;
const osMutexAttr_t lvgl_mutex_attributes = {
  .name = "lvgl_mutex"
};
/* USER CODE END Variables */
/* Definitions for uart_task */
osThreadId_t uart_taskHandle;
const osThreadAttr_t uart_task_attributes = {
  .name = "uart_task",
  .stack_size = 512 * 4,
  .priority = (osPriority_t) osPriorityNormal4,
};
/* Definitions for lvgl_task */
osThreadId_t lvgl_taskHandle;
const osThreadAttr_t lvgl_task_attributes = {
  .name = "lvgl_task",
  .stack_size = 1024 * 4,
  .priority = (osPriority_t) osPriorityLow2,
};
/* Definitions for animation_task */
osThreadId_t animation_taskHandle;
const osThreadAttr_t animation_task_attributes = {
  .name = "animation_task",
  .stack_size = 512 * 4,
  .priority = (osPriority_t) osPriorityLow3,
};
/* Definitions for monitor_task */
osThreadId_t monitor_taskHandle;
const osThreadAttr_t monitor_task_attributes = {
  .name = "monitor_task",
  .stack_size = 256 * 4,
  .priority = (osPriority_t) osPriorityLow1,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void uart_task_function(void *argument);
void lvgl_task_function(void *argument);
void animation_task_function(void *argument);
void system_monitor_task_function(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* 创建LVGL互斥锁，用于保护UI操作 */
  lvgl_mutexHandle = osMutexNew(&lvgl_mutex_attributes);
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of uart_task */
  uart_taskHandle = osThreadNew(uart_task_function, NULL, &uart_task_attributes);

  /* creation of lvgl_task */
  lvgl_taskHandle = osThreadNew(lvgl_task_function, NULL, &lvgl_task_attributes);

  /* creation of animation_task */
  animation_taskHandle = osThreadNew(animation_task_function, NULL, &animation_task_attributes);

  /* creation of monitor_task */
  monitor_taskHandle = osThreadNew(system_monitor_task_function, NULL, &monitor_task_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_uart_task_function */
/**
  * @brief  Function implementing the uart_task thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_uart_task_function */
void uart_task_function(void *argument)
{
  /* USER CODE BEGIN uart_task_function */
  printf("UART Task Started\n");
  
  /* Infinite loop */
  for(;;)
  {
    // 这里可以处理串口接收和发送
    // 目前保持简单，定期输出系统状态
    if (osMutexAcquire(lvgl_mutexHandle, 100) == osOK) {
      printf("System running - FPS: %d\n", current_fps);
      osMutexRelease(lvgl_mutexHandle);
    }
    osDelay(1000); // 1秒周期
  }
  /* USER CODE END uart_task_function */
}

/* USER CODE BEGIN Header_lvgl_task_function */
/**
* @brief Function implementing the lvgl_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_lvgl_task_function */
void lvgl_task_function(void *argument)
{
  /* USER CODE BEGIN lvgl_task_function */
  // 初始化LVGL
  printf("Initializing LVGL...\n");
  lv_init();
  lv_port_disp_init();
  lv_port_indev_init();
  
  // 初始化UI
  printf("UI Initializing...\n");
  UI_Init();
  printf("UI Initialized.\n");
  
  // 初始化时间基准
  last_time = osKernelGetTickCount();
  
  /* Infinite loop */
  for(;;)
  {
    // 获取互斥锁保护LVGL操作
    if (osMutexAcquire(lvgl_mutexHandle, osWaitForever) == osOK) {
      // 处理LVGL定时器
      lv_timer_handler();
      
      // 增加帧率计数
      frame_count++;
      
      osMutexRelease(lvgl_mutexHandle);
    }
    
    // 提高帧率到约60FPS
    osDelay(16); // 约60FPS
  }
  /* USER CODE END lvgl_task_function */
}

/* USER CODE BEGIN Header_animation_task_function */
/**
* @brief Function implementing the animation_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_animation_task_function */
void animation_task_function(void *argument)
{
  /* USER CODE BEGIN animation_task_function */
  printf("Animation Task Started\n");
  
  /* Infinite loop */
  for(;;)
  {
    // 获取互斥锁保护动画操作
    if (osMutexAcquire(lvgl_mutexHandle, 100) == osOK) {
      // 这里可以实现各种动画效果
      // 例如：更新UI元素位置、透明度等
      
      // 示例动画：闪烁FPS显示
      if (current_fps > 32) {
        // 如果FPS过高，可以降低更新频率
        lv_tick_inc(1);
      }
      
      osMutexRelease(lvgl_mutexHandle);
    }
    
    // 动画任务可以稍微快一点，但不要太频繁
    osDelay(20); // 50Hz更新频率
  }
  /* USER CODE END animation_task_function */
}

/* USER CODE BEGIN Header_system_monitor_task_function */
/**
* @brief Function implementing the monitor_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_system_monitor_task_function */
void system_monitor_task_function(void *argument)
{
  /* USER CODE BEGIN system_monitor_task_function */
  printf("System Monitor Task Started\n");
  
  // 启动TIM6用于FPS监控
  HAL_TIM_Base_Start_IT(&htim6);
  
  /* Infinite loop */
  for(;;)
  {
    // 检查是否到了计算FPS的时间点
    if (UpdateTimer) {
      // 计算FPS
      uint32_t current_time = osKernelGetTickCount();
      float elapsed_time = (current_time - last_time) / 1000.0f;
      current_fps = (uint8_t)(frame_count / elapsed_time);
      
      // 重置计数器
      frame_count = 0;
      last_time = current_time;
      UpdateTimer = 0;
      
      // 显示实际FPS值，不再限制范围
      printf("Current FPS: %d\n", current_fps);
      
      // 确保FPS大于30
      if (current_fps <= 30) {
        printf("Warning: FPS too low (%d), optimizing...\n", current_fps);
      }
    }
    
    // 监控任务低频率运行
    osDelay(100); // 10Hz监控频率
  }
  /* USER CODE END system_monitor_task_function */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

// LVGL tick处理函数，由FreeRTOS系统滴答调用
void vApplicationTickHook(void)
{
  /* This function will be called by each tick interrupt if configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. 
   We use this to update the LVGL tick count */
  // 注意：在中断上下文中不应使用互斥锁
  lv_tick_inc(1);
}

/* USER CODE END Application */

